﻿using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Layout;
using DevExpress.XtraTreeList;
using DevExpress.XtraVerticalGrid;
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Linq;
using DevExpress.XtraEditors.Container;
using Inaction.ServiceContract;

namespace Inaction.UI
{
    public partial class BarManager : DevExpress.XtraBars.BarManager
    {
        #region 方法
        internal void ApplyFormRules()
        {
            if (MasterBindingInfo == null || MasterBindingInfo.BindingSource == null) return;
            if (!MasterBindingInfo.TypeIsList)
            {
                BtnQuery.Enabled = false;
            }
            else
            {
                BtnQuery.Enabled = FormManager.IsAllowExecute(BtnQuery.Name);
            }

            BtnSave.Enabled = EditMode || MasterBindingInfo.IsDirty;
            BtnAddNew.Enabled = FormManager.IsAllowExecute(BtnAddNew.Name)
                && CurrentBindingInfo != null && CurrentBindingInfo.AllowNew;
            if (!MasterBindingInfo.TypeIsList)//单条数据时,编辑状态不可新增
            {
                BtnAddNew.Enabled = !EditMode && BtnAddNew.Enabled;
            }
            BtnModify.Enabled = FormManager.IsAllowExecute(BtnModify.Name)
                && !EditMode && CurrentBindingInfo != null && CurrentBindingInfo.AllowEdit;
            BtnDelete.Enabled = FormManager.IsAllowExecute(BtnDelete.Name)
                 && CurrentBindingInfo != null
                 && (CurrentBindingInfo.AllowRemove || CurrentBindingInfo.CurrentBusiness != null && CurrentBindingInfo.CurrentBusiness.IsNew)
                 && !(bindingInfos.Any(
                                     p => p != CurrentBindingInfo && p.BindingSource.Current != null
                                         && p.BindingSource.DataSource == CurrentBindingInfo.BindingSource));
            BtnExport.Enabled = FormManager.IsAllowExecute(BtnExport.Name)
                && CurrentBindingInfo != null && CurrentBindingInfo.HasData;
            BtnPrint.Enabled = CurrentBindingInfo != null && CurrentBindingInfo.HasData;
            BtnCancel.Enabled = EditMode;

            SetEditorsReadOnly(!EditMode);
            SetEditorContainers();
            ApplyControlsExtend();
            if (FormRulesApplied != null)
            {
                FormRulesApplied(this, null);
            }
        }

        internal void ApplyFormRules(BindingInfo bindingInfo = null)
        {
            if (this.Form != null)
            {
                var f = GetForm();
                f.ValidateChildren(ValidationConstraints.Enabled);
            }
            if (bindingInfo == null) bindingInfo = MasterBindingInfo;
            if (bindingInfo == null || bindingInfo.BindingSource == null) return;
            BtnAddNew.Enabled = FormManager.IsAllowExecute(BtnAddNew.Name)
                && bindingInfo != null && bindingInfo.AllowNew;
            if (!MasterBindingInfo.TypeIsList && bindingInfo == MasterBindingInfo)//单条数据时,当前数据为主数据时不可新增
            {
                BtnAddNew.Enabled = BtnAddNew.Enabled && !EditMode;
            }
            BtnSave.Enabled = EditMode || MasterBindingInfo.IsDirty;
            BtnModify.Enabled = FormManager.IsAllowExecute(BtnModify.Name)
                && !EditMode && bindingInfo != null && bindingInfo.AllowEdit;
            BtnDelete.Enabled = FormManager.IsAllowExecute(BtnDelete.Name)
               && bindingInfo != null
               && (bindingInfo.AllowRemove || (bindingInfo.CurrentBusiness != null && bindingInfo.CurrentBusiness.IsNew))
               && !(bindingInfos.Any(
                                   p => p != bindingInfo
                                       && p.BindingSource.Current != null
                                       && p.BindingSource.DataSource == bindingInfo.BindingSource));

            BtnExport.Enabled = FormManager.IsAllowExecute(BtnExport.Name)
                && bindingInfo != null && bindingInfo.HasData;
            BtnPrint.Enabled = bindingInfo != null && bindingInfo.HasData;
            BtnCancel.Enabled = EditMode;

            SetEditorsReadOnly(!EditMode, bindingInfo);
            SetEditorContainers();
            ApplyControlsExtend();
            if (FormRulesApplied != null)
            {
                FormRulesApplied(this, null);
            }
        }

        private bool CheckError(out string error)
        {
            error = string.Empty;
            foreach (var bindingInfo in BindingInfos)
            {
                if (bindingInfo.BindingSource.List.Count == 0) continue;
                foreach (IDataErrorInfo item in bindingInfo.BindingSource.List)
                {
                    error = item.Error;
                    if (!string.IsNullOrEmpty(error))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        public void ShowMessage(string message)
        {
            BarItemText.Caption = message;
            BarItemText.Hint = message;
        }
        internal void ShowWaitDialog(string text)
        {
            waitDialog.Visible = true;
            waitDialog.Caption = text;
            waitDialog.Show();
        }
        internal void HideWaitDialog()
        {
            waitDialog.Visible = false;
            waitDialog.Hide();
        }
        void BindingSourceBindingComplete(object sender, BindingCompleteEventArgs e)
        {
            ShowCurrentSourceInfo();
        }
        void BindingSourcePositionChanged(object sender, EventArgs e)
        {
            ShowCurrentSourceInfo();
            ApplyFormRules(CurrentBindingInfo);
        }
        void SetEditorContainers()
        {
            if (CurrentBindingInfo == null || !formManager.BindingEditorContainers.ContainsKey(CurrentBindingInfo.BindingSource)) return;

            var editorControls = formManager.BindingEditorContainers[CurrentBindingInfo.BindingSource];
            var editable = EditMode && CurrentBindingInfo.AllowGridEdit && CurrentBindingInfo.HasData;
            foreach (var editorControl in editorControls)
            {
                if (editorControl is GridControl)
                {
                    var control = editorControl as GridControl;
                    foreach (var view in control.Views)
                    {
                        var cv = view as ColumnView;
                        if (cv == null) continue;
                       cv.OptionsBehavior.ReadOnly = !editable;
                       cv.OptionsBehavior.Editable = editable;
                    }
                }
                else if (editorControl is TreeList)
                {
                    var treeList = editorControl as TreeList;
                    treeList.OptionsBehavior.Editable = editable;
                }
                else if (editorControl is VGridControl)
                {
                    var vGrid = editorControl as VGridControl;
                    vGrid.OptionsBehavior.Editable = editable;
                }
            }
        }
        void SetEditorsReadOnly(bool readOnly, BindingInfo bindingInfo = null)
        {
            if (bindingInfo == null)
            {
                foreach (var b in this.BindingInfos)
                {
                    formManager.SetEditorsReadOnly(b, readOnly || !(b.AllowEdit && b.HasData));
                }
            }
            else
            {
                formManager.SetEditorsReadOnly(bindingInfo, readOnly || !(bindingInfo.AllowEdit && bindingInfo.HasData));
            }
        }
        void SetStateText(string text)
        {
            BarItemState.Caption = text;
        }

        public void FocusedToSource(BindingSource bindingSource)
        {
            var bindingInfo = BindingInfos.FirstOrDefault(p => p.BindingSource == bindingSource);
            if (bindingInfo == null) return;
            FocusedToFirstControl(bindingInfo);
        }
        #endregion

        #region 静态方法
        public static BarManager GetBarManager(Form form)
        {
            if (form == null) return null;

            if (form is BaseForm && (form as BaseForm).BarManager != null)
            {
                return (form as BaseForm).BarManager;
            }
            else
            {
                if (form.Container != null)
                {
                    try
                    {
                        var enumerator = form.Container.Components.GetEnumerator();
                        enumerator.MoveNext();
                        while (enumerator.Current != null)
                        {
                            if (enumerator.Current is BarManager)
                            {
                                return enumerator.Current as BarManager;
                            }
                            enumerator.MoveNext();
                        }
                    }
                    catch { }
                }

                var fields = form.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.CreateInstance | System.Reflection.BindingFlags.Instance);
                var field = fields.FirstOrDefault(p => p.FieldType == typeof(BarManager));
                if (field != null)
                {
                    return field.GetValue(form) as BarManager;
                }
                return null;
            }
        }

        
        #endregion
    }
}
